﻿Imports MindFusion.Diagramming
Imports MindFusion.Drawing

Public Module ModDrawing
    'represents base graphic enumerations and operations

#Region "Subs"
    'drawing a text
    Public Sub DrawText(ByRef IoEvent As DrawLinkEventArgs, ByVal InX As Single, ByVal InY As Single)
        ' ''    Dim font As Font = New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel)
        ' ''    Dim defaultIcon As Bitmap = New Bitmap(50, 50)
        ' ''    Dim graphics As Graphics = graphics.FromImage(defaultIcon)

        ' ''    'graphics.DrawString("b", font, Brushes.Blue, InX, InY)
        ' ''    IoEvent.Graphics.DrawString("abcdefg", font, Brushes.Blue, InX, InY)
        ' ''    'IoEvent.Graphics.DrawString("123456", font, Brushes.Blue, New RectangleF(InX, InY, 20, 20))
        ' ''    'IoEvent.Graphics.DrawImage(XtraForm1.imlPanels.Images(0), InX, InY)
        ' ''    IoEvent.Graphics.ResetClip()
        ' ''    Dim g As Graphics = XtraForm1.fcDiagramView.CreateGraphics
        ' ''    'g.Clip=  'Clear(Color.Transparent)
        ' ''    'g.DrawString("123456", font, Brushes.Blue, InX, InY)
        ' ''    g.Clear(Color.Transparent)
        ' ''    'g.DrawImage(XtraForm1.imlPanels.Images(0), InX, InY)
        ' ''    font.Dispose()

        ' ''    'IoEvent.Graphics. 
    End Sub
    'drawing triangle for note indication
    Public Sub DrawNoteTriangle(ByVal IoNode As DiagramNode, ByVal IoGraphics As IGraphics)
        If IsNodeConnectedToNote(IoNode) Then
            Dim LoPoints() As PointF = { _
            New PointF(IoNode.Bounds.Right - 2, IoNode.Bounds.Top), _
            New PointF(IoNode.Bounds.Right, IoNode.Bounds.Top), _
            New PointF(IoNode.Bounds.Right, IoNode.Bounds.Top + 2)}

            Dim LoBrush As Drawing.SolidBrush = New Drawing.SolidBrush(Drawing.Color.Red)
            IoGraphics.FillPolygon(LoBrush, LoPoints)
        End If
    End Sub
#End Region
#Region "Functions"
#Region "MindFusion Functions - MF"
    'MindFusion Pen creator
    Public Function MFPenVirginCreator(ByVal IoColor As Drawing.Color, ByVal IdcWidth As Decimal) As Pen
        Return New Pen(IoColor, IdcWidth)
    End Function
    'MindFusion SolidBrush creator
    Public Function MFSolidBrushVirginCreator(ByVal IoColor As Drawing.Color) As SolidBrush
        Return New SolidBrush(IoColor)
    End Function
    'MindFusion LinearGradientBrush creator
    Public Function MFLinearGradientBrushCreator(ByVal IoBeginColor As Drawing.Color, ByVal IoEndColor As Drawing.Color, ByVal InAngle As Single) As LinearGradientBrush
        Return New LinearGradientBrush(IoBeginColor, IoEndColor, InAngle)
    End Function
    'MindFusion AnchorPoint creator
    Public Function MFAnchorPointVirginCreator(ByVal IiX As Integer, ByVal IiY As Integer, ByVal IbAllowIncoming As Boolean, ByVal IbAllowOutgoing As Boolean, ByVal IoMarkStyle As MarkStyle, ByVal IoColor As Drawing.Color) As AnchorPoint
        Return New AnchorPoint(IiX, IiY, IbAllowIncoming, IbAllowOutgoing, IoMarkStyle, IoColor)
    End Function
#End Region
#Region "System.Drawing Functions - SD"
    'System.Drawing Pen creator
    Public Function SDPenVirginCreator(ByVal IoColor As Drawing.Color, ByVal IdcWidth As Decimal) As Drawing.Pen
        Return New Drawing.Pen(IoColor, IdcWidth)
    End Function
    'System.Drawing PointF creator
    Public Function SDPointFVirginCreator(ByVal IiX As Integer, ByVal IiY As Integer) As Drawing.PointF
        Return New Drawing.PointF(IiX, IiY)
    End Function
    'System.Drawing Rectangle creator
    Public Function SDRectangleVirginCreator(ByVal IiX As Integer, ByVal IiY As Integer, ByVal IiWidth As Integer, ByVal IiHeight As Integer) As Drawing.Rectangle
        Return New Drawing.Rectangle(IiX, IiY, IiWidth, IiHeight)
    End Function
    'System.Drawing RectangleF creator
    Public Function SDRectangleFVirginCreator(ByVal InX As Single, ByVal InY As Single, ByVal InWidth As Single, ByVal InHeight As Single) As Drawing.RectangleF
        Return New Drawing.RectangleF(InX, InY, InWidth, InHeight)
    End Function
#End Region
#Region "Common Functions"
    'creating of anchor pattern
    Public Function CreateAnchorPatternSurrounding(ByVal IiNumberOfPoints As Integer) As AnchorPattern
        'IiNumberOfPoints = number of points on one edge of rectangle, final number is 4xIiNumberOfPoints  
        Dim LoAnchorPattern = New AnchorPattern(New AnchorPoint() {})

        If IiNumberOfPoints < 1 Then IiNumberOfPoints = 9 'verification, 9 is default
        'calculating gap between points
        Dim LdcGap As Decimal = Math.Round(100 / (IiNumberOfPoints + 1), 3) '3 is precision (number of fractional digits)
        Dim LdcJ As Decimal = 0

        For LiI As Integer = 1 To IiNumberOfPoints
            LdcJ += LdcGap
            LoAnchorPattern.Points.Add(New AnchorPoint(LdcJ, 0, True, True, MarkStyle.X, Color.Aqua)) 'top edge
            LoAnchorPattern.Points.Add(New AnchorPoint(100, LdcJ, True, True, MarkStyle.X, Color.Aqua)) 'right edge
            LoAnchorPattern.Points.Add(New AnchorPoint(LdcJ, 100, True, True, MarkStyle.X, Color.Aqua)) 'bottom edge
            LoAnchorPattern.Points.Add(New AnchorPoint(0, LdcJ, True, True, MarkStyle.X, Color.Aqua)) 'left edge
        Next
        Return LoAnchorPattern
    End Function
    'returns edge of rectangle the point is on (used when drawing right position of a links point)
    Public Function GetEdgeForLink(ByVal InX As Single, ByVal InY As Single, ByVal IoBounds As RectangleF) As GeEdgeForLink
        If InX = IoBounds.Left Then
            'left
            Return GeEdgeForLink.kkLeft
        ElseIf InX = IoBounds.Right Then
            'right
            Return GeEdgeForLink.kkRight
        ElseIf InY = IoBounds.Top Then
            'top
            Return GeEdgeForLink.kkTop
        ElseIf InY = IoBounds.Bottom Then
            'bottom
            Return GeEdgeForLink.kkBottom
        Else
            'nowhere
            Return GeEdgeForLink.kkNoEdge
        End If
    End Function
    'returns edge of rectangle the point is on (used to determine right operation for resizing a node)
    Public Function GetEdgeForResize(ByVal InX As Single, ByVal InY As Single, ByVal IoBounds As RectangleF, ByVal IdbThreshold As Double) As GeEdgeForResize
        If (InX >= IoBounds.Left - IdbThreshold) And (InX <= IoBounds.Left + IdbThreshold) And (InY >= IoBounds.Top - IdbThreshold) And (InY <= IoBounds.Top + IdbThreshold) Then
            'top left corner 
            Return GeEdgeForResize.kkTopLeftCorner
        ElseIf (InX >= IoBounds.Right - IdbThreshold) And (InX <= IoBounds.Right + IdbThreshold) And (InY >= IoBounds.Top - IdbThreshold) And (InY <= IoBounds.Top + IdbThreshold) Then
            'top right corner 
            Return GeEdgeForResize.kkTopRightCorner
        ElseIf (InX >= IoBounds.Right - IdbThreshold) And (InX <= IoBounds.Right + IdbThreshold) And (InY >= IoBounds.Bottom - IdbThreshold) And (InY <= IoBounds.Bottom + IdbThreshold) Then
            'bottom right corner 
            Return GeEdgeForResize.kkBottomRightCorner
        ElseIf (InX >= IoBounds.Left - IdbThreshold) And (InX <= IoBounds.Left + IdbThreshold) And (InY >= IoBounds.Bottom - IdbThreshold) And (InY <= IoBounds.Bottom + IdbThreshold) Then
            'bottom left corner 
            Return GeEdgeForResize.kkBottomLeftCorner
        ElseIf (InX >= IoBounds.Left - IdbThreshold) And (InX <= IoBounds.Left + IdbThreshold) Then
            'left
            Return GeEdgeForResize.kkLeft
        ElseIf (InX >= IoBounds.Right - IdbThreshold) And (InX <= IoBounds.Right + IdbThreshold) Then
            'right
            Return GeEdgeForResize.kkRight
        ElseIf (InY >= IoBounds.Top - IdbThreshold) And (InY <= IoBounds.Top + IdbThreshold) Then
            'top
            Return GeEdgeForResize.kkTop
        ElseIf (InY >= IoBounds.Bottom - IdbThreshold) And (InY <= IoBounds.Bottom + IdbThreshold) Then
            'bottom
            Return GeEdgeForResize.kkBottom
        Else
            'nowhere
            Return GeEdgeForResize.kkNoEdge
        End If
    End Function
    'returns if PointF is in Rectangle
    ' ''Public Function IsPointInRectangle(ByVal IoRectangle As Rectangle, ByVal IoPointF As PointF) As Boolean
    ' ''    Return (IoPointF.X >= IoRectangle.Left) And (IoPointF.X <= IoRectangle.Right) And (IoPointF.Y >= IoRectangle.Top) And (IoPointF.Y <= IoRectangle.Bottom)
    ' ''End Function
    '' ''returns if PointF is in RectangleF
    ' ''Public Function IsPointInRectangleF(ByVal IoRectangleF As RectangleF, ByVal IoPointF As PointF) As Boolean
    ' ''    Return (IoPointF.X >= IoRectangleF.Left) And (IoPointF.X <= IoRectangleF.Right) And (IoPointF.Y >= IoRectangleF.Top) And (IoPointF.Y <= IoRectangleF.Bottom)
    ' ''End Function
    'returns colors whole name (if color has name) or in RGB numbers
    Public Function GetNameOrRGBColor(ByVal IoColor As Color) As String
        Return IIf(IoColor.IsNamedColor, IoColor.Name, IoColor.R.ToString & "; " & IoColor.G.ToString & "; " & IoColor.B.ToString)
    End Function
    'returns description of LinearGradientBrush in format "BeginColor --> EndColor, Angle°"
    Public Function GetDescriptionOfLinearGradientBrush(ByVal IoBrush As LinearGradientBrush) As String
        Return GetNameOrRGBColor(IoBrush.LinearColors(0)) & " --> " & GetNameOrRGBColor(IoBrush.LinearColors(1)) & ", " & IoBrush.Angle.ToString & "°"
    End Function
    'returns description of Pen in format "Color; Width"
    Public Function GetDescriptionOfPen(ByVal IoPen As Pen) As String
        Return GetNameOrRGBColor(IoPen.Color) & "; " & IoPen.Width.ToString
    End Function
    'returns center of rectangle
    Public Function CenterOfRectangle(ByVal IoRectangle As Rectangle) As PointF
        Return New PointF(IoRectangle.Left + (IoRectangle.Width / 2), IoRectangle.Top + (IoRectangle.Height / 2))
    End Function
    'returns center of rectangleF
    Public Function CenterOfRectangle(ByVal IoRectangle As RectangleF) As PointF
        Return New PointF(IoRectangle.Left + (IoRectangle.Width / 2), IoRectangle.Top + (IoRectangle.Height / 2))
    End Function
    'gets if this node is connected to any note
    Public Function IsNodeConnectedToNote(ByVal IoNode As DiagramNode) As Boolean
        Dim LoDiagramLinkCollection As DiagramLinkCollection = IoNode.GetAllLinks
        Dim LbResult As Boolean = False

        For Each LoMMLinkNode As ClsMMLinkNode In LoDiagramLinkCollection
            If LoMMLinkNode.MMTypeOfLink = GeTypeOfLink.kkNote Then
                LbResult = True
                ' ''Dim LoRandom As Random = New Random
                '' ''TEMP! TEMP! TEMP! TEMP! TEMP! TEMP!
                ' ''Select Case IoNode.GetType.Name
                ' ''    Case "ClsMMTableNode"
                ' ''        Dim LoMMTableNode As ClsMMTableNode = CType(IoNode, ClsMMTableNode)
                ' ''        Debug.Print(LoMMTableNode.Caption)
                ' ''    Case "ClsMMContainerNode"
                ' ''        Dim LoMMContainerNode As ClsMMContainerNode = CType(IoNode, ClsMMContainerNode)
                ' ''        Debug.Print(LoMMContainerNode.Caption)
                ' ''    Case "ClsMMShapeNode"
                ' ''        Dim LoMMShapeNode As ClsMMShapeNode = CType(IoNode, ClsMMShapeNode)
                ' ''        Debug.Print(LoMMShapeNode.Text)
                ' ''End Select
                ' ''Debug.Print("IsNodeConnectedToNote" & LoRandom.Next)
                '' ''TEMP! TEMP! TEMP! TEMP! TEMP! TEMP!
                Exit For
            End If
        Next

        Return LbResult
    End Function
#End Region
#End Region

End Module
